#include "common_thread.h"
#include <sys/select.h>
#include <string.h>
#include "gk.h"

#define SILICON_BLE_MODULE_VERSION		"BT_MODULE_V3.2.10.464"
#define SILICON_BLE_INTERFACE 			"/dev/ttyS0"
#define SILICON_BLE_BOARDRATE			500000

void func(int cmd);
int parse_argv(char **argv, int argv_len, char *buf)
{
    int argc = 0;
    char *cp = buf;
    char *dest = buf;
    char quote;
    char c;

    while (argc < argv_len && *cp != '\0')
    {
        /*
         * Skip leading blanks and tabs.
         */
        while ((c = *cp) != '\0' && (c == ' ' || c == '\t'))
        {
            cp++;
        }
        if (c == '\0')
        {
            break;
        }

        /*
         * copy arg and skip until next blank, tab, or end of string.
         * If quoted, look for matching quote.
         */
        quote = 0;
        *argv++ = cp;
        argc++;
        for (dest = cp; (c = *cp) != '\0'; cp++)
        {
            if (quote)
            {
                if (c == quote)
                {
                    quote = 0;
                    continue;
                }
            }
            else
            {
                /*
                 * Look for start quote.
                 */
                if (c == '\'' || c == '\"')
                {
                    quote = c;
                    continue;
                }
                if (c == ' ' || c == '\t')
                {
                    break;
                }
            }
            *dest++ = c;
        }
        *dest = '\0';
        if (c == '\0')
        {
            break;
        }
        cp++;
    }
    if (argc < argv_len)
    {
        *argv = 0;
    }
    return argc;
}
void cmd_in_buffer(char *buf, int size, int type)
{

    if (strcmp(buf, "") != 0)
    {
        // CMD_LOG_WARN("console input:[%s]", buf);
        char *argv[20];
        int argc;
        argc = parse_argv(argv, sizeof(argv), buf);

        //stCmd_t *cmd = cmd_search(argv[0]);
        char* cmd = argv[0];
        if (cmd == NULL)
        {
            printf("invalid cmd!");
        }
        else
        {
            //printf("test cmd\n");
            int num = atoi(cmd);
            func(num);
            // do something
        }
    }
    else
    {
        //fprintf(stdout,"get:%s\n",buf);
    }
    fprintf(stdout, "%s\r\n", "$");
}

void cmd_in(void *arg, int fd)
{
    char buf[1024];
    int size = 0;

    int ret = read(fd, buf, sizeof(buf));
    if (ret < 0)
    {
        printf("what happend?");
        return;
    }

    if (ret == 0)
    {
        printf("error!");
        return;
    }

    size = ret;
    buf[size] = 0;
    if (size >= 1 && buf[size - 1] == '\n')
    {
        buf[size - 1] = 0;
        size--;
    }
    char *p = buf;
    while (*p == ' ')
    {
        p++;
        size--;
    }
    if (size > 0)
    {
        memcpy(buf, p, size);
    }
    else
    {
        buf[0] = 0;
        size = 0;
    }

    cmd_in_buffer(buf, size, 1);
}

void* gk_thread(void* arg) {

    //blufi_impl_silicon_t* silicon_impl = (blufi_impl_silicon_t*)arg;

    //silicon_impl->thread_running = RB_TRUE;
    while (1) {
        /**> loop */
		int maxfd = 0;
		fd_set	fds;
		FD_ZERO(&fds);

        /**> gecko */
		int gfd = gk_get_fd();
		if (gfd > 0){
			FD_SET(gfd, &fds);
			if (gfd > maxfd) {
				maxfd = gfd;
			}
		}
        FD_SET(0, &fds);

        struct timeval	tv;
        tv.tv_sec = 1;
        int ret = select(maxfd + 1, &fds, NULL, NULL, &tv);
		if (ret == 0) {
			//log_warn("select timer fd faild maxfd : %d.", maxfd);
			continue;
		}
        else if (ret < 0) {
            break;
        }

        /**> gecko */
		if (gfd > 0) {
			if (FD_ISSET(gfd, &fds)) {
				gk_loop();
			}	
		}
        if(FD_ISSET(0, &fds))
        {
            cmd_in((void *)1,0);
        }
    }

    //silicon_impl->thread_running = RB_FALSE;
}

enum CMD_T{
    init=1,
    startadv=2,
    stopadv=3,
    send_data=4,
    hello=5,
    start=6,
    stop=7,

};




static int hell0 = 0;
int b_status = BLUFI_IDLE;
void func(int cmd)
{
    switch(cmd)
    {
        case init:
        {
            gk_init();
            gk_open(SILICON_BLE_INTERFACE,SILICON_BLE_BOARDRATE);
        }
        break;
        case startadv:
        {
            gk_advertiser_start();
        }
        break;
        case stopadv:
        {
            gk_advertiser_stop();
        }
        break;
        case send_data:
        {
           // gk_hello();
            uint8_t bcnBeaconAdvData[] = {
                0x02, 0x01, 0x06,
                0x13, 0xff,
                0x00, 0x00,
                'd','u','s','u','n', //identify
                0xff, 0xff, 0xff, 0xff, 0xff, 0xff, //mac
                0x00, 0x30, //pid
                0x01, //If you want a one-click distribution network with gateway, set it to 1.
                0x01, //version
                0x02, //type, 1->common ble, 2->doul ble, 3->doul mesh, 4->android screen ble
                0x05, 0x12, 0x00, 0x06, 0x0c, 0x80
            };
            gk_set_beacon_adv_data(bcnBeaconAdvData,sizeof(bcnBeaconAdvData));;
            //设置扫描响应
            char* sn = "DG0090N00066";
            uint8_t bcnBeaconAdvRspData[32] = {0};
            bcnBeaconAdvRspData[0] = (strlen(sn) + 1)&0xff;
            bcnBeaconAdvRspData[1] = 0x09; // 09 type 设备简称
            memcpy(&bcnBeaconAdvRspData[2], sn, strlen(sn));
            gk_set_beacon_adv_rsp_data(bcnBeaconAdvRspData,strlen(sn)+2);
            printf("sn:%s,len=%d\n",sn,strlen(sn));

            //  gk_hello();
             hell0 =1;
        }
        break;
        case hello:
        {
            gk_hello();
        }
        break;
        case stop:
        gk_close();
        break;
    }
}

int main()
{
    RB_INT32 iRet = RB_OK;
    char buf[1024+1];
    pthread_t stThread;
    //1. open uart
    gk_open(SILICON_BLE_INTERFACE,SILICON_BLE_BOARDRATE);

    //0. init stack
    gk_init();

    //设置mac
    char *mac ="30:ae:7b:e8:2f:aa";
    gk_set_mac(mac);

    //2. regist evt handle
    iRet = rb_pthread_create(&stThread, COMMON_THREAD_PRIO_MIDDLE, THREAD_STACK_MIN_VAL, gk_thread, RB_NULL);
    
    //接受指令
    ssize_t res = 0;
    int count = 0;
    for (;;)
    {
        //int cmdNum =0;
       // memset(buf, '\0', sizeof(buf));
       // scanf("%s",buf);
        //printf("get a param");
       // cmd_in_buffer(buf, 1024, 1);
       // fflush(stdin);
       usleep(100000);
       if(hell0)
       {
            //gk_advertiser_start();
            if(b_status == BLUFI_HELLO_SUCC)
            {
                gk_advertiser_start();
                b_status = BLUFI_START_ADV_SUCC;
            }
            if(b_status == BLUFI_IDLE)
            {
                gk_hello();
            }
            if(b_status == BLUFI_START_ADV_SUCC&&(count++%50==0))
            {

                gk_server_notify_battery(NULL,0);
            }
       }
    }
    return 0;;
}